using java.applet;
using java.awt.@event;
using System;

namespace com.abstractatech.gamification.tdjdosboxe
{
    using java.awt.image;
    using System.Text;
    using System.Xml.Linq;
    using InternalKeyHandler = Action<int, int>;
    using StringKeyHandler = Action<string, string>;

    public class InternalApplicationApplet :
        jdos.gui.MainApplet
    {

        //        InternalMain UnhandledException:
        //{ FullName = System.IO.IOException, InnerException =  }

        //{ ExceptionObject = System.IO.IOException: The directory is not empty.

        //   at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive, Boolean throwOnTopLevelDirectoryNotFound)
        //   at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive, Boolean checkHost)
        //   at System.IO.Directory.Delete(String path, Boolean recursive)
        //   at jsc.meta.Tools.ToolsExtensions.ToJava(FileInfo TargetAssembly, DirectoryInfo javapath, MethodInfo assembly_metaentrypoint, FileInfo FusionAssembly, Strin

        public event InternalKeyHandler InternalKeyDown;
        public event InternalKeyHandler InternalKeyUp;

        public override void keyPressed(KeyEvent value)
        {
            var KeyChar = (int)value.getKeyChar();
            var KeyCode = value.getKeyCode();

            if (InternalKeyDown != null)
                InternalKeyDown(KeyChar, KeyCode);

            base.keyPressed(value);
        }

        public override void keyReleased(KeyEvent value)
        {
            var KeyChar = (int)value.getKeyChar();
            var KeyCode = value.getKeyCode();

            if (InternalKeyUp != null)
                InternalKeyUp(KeyChar, KeyCode);

            base.keyReleased(value);
        }

    }


    public sealed class ApplicationApplet : InternalApplicationApplet
    {
        public const int DefaultWidth = 644;
        public const int DefaultHeight = 404;

        public event StringKeyHandler __KeyDown;
        public event StringKeyHandler __KeyUp;

        public void WhenReady(Action yield)
        {
            InternalKeyDown +=
                (keyChar, keyCode) =>
                {
                    if (__KeyDown != null)
                        __KeyDown("" + keyChar, "" + keyCode);
                };

            InternalKeyUp +=
                (keyChar, keyCode) =>
                {
                    if (__KeyUp != null)
                        __KeyUp("" + keyChar, "" + keyCode);
                };


            yield();
        }

        int __previous_shadow_checksum;

        public void __GetPixels(Action<string> set_boxShadow)
        {
            BufferedImage __buffer = new BufferedImage(DefaultWidth, DefaultHeight, BufferedImage.TYPE_INT_RGB);

            var gg = __buffer.getGraphics();

            base.update(gg);


            //190px -150px   50px -180px yellow, 
            //  190px -120px   50px -180px red, 
            //  190px  -90px   50px -180px blue ,
            //  190px  -60px   50px -180px white ,
            //  190px -30px    50px -180px purple,
            //  190px -0px     50px -180px lime

            var w = new StringBuilder();

            var nonblackany = false;

            var shadow_checksum = 0;

            Func<int, int, string> rgb =
                (x, y) =>
                {
                    var c = __buffer.getRGB(x, y);

                    var u = c & 0xffffff;

                    //Console.WriteLine(new { x, y, c, u });
                    shadow_checksum ^= u;

                    return "#" + u.ToString("x8").Substring(2);
                };

            Func<int, int, string> rightglow =
                (y, radius) =>
                {
                    return "180px " + y + "px " + radius + "px -180px " + rgb(DefaultWidth - 16, y + DefaultHeight / 2);
                };

            Func<int, int, string> leftglow =
              (y, radius) =>
              {
                  return "-180px " + y + "px " + radius + "px -180px " + rgb(16, y + DefaultHeight / 2);
              };



            w.AppendLine(leftglow(-180, 40) + ", ");
            w.AppendLine(leftglow(-150, 50) + ", ");
            w.AppendLine(leftglow(-120, 60) + ", ");
            w.AppendLine(leftglow(-90, 60) + ", ");
            w.AppendLine(leftglow(-60, 60) + ", ");
            w.AppendLine(leftglow(-30, 50) + ", ");
            w.AppendLine(leftglow(-0, 40) + ", ");
            w.AppendLine(leftglow(30, 40) + ", ");
            w.AppendLine(leftglow(60, 40) + ", ");
            w.AppendLine(leftglow(90, 40) + ", ");
            w.AppendLine(leftglow(120, 40) + ", ");

            w.AppendLine(rightglow(-180, 40) + ", ");
            w.AppendLine(rightglow(-150, 50) + ", ");
            w.AppendLine(rightglow(-120, 60) + ", ");
            w.AppendLine(rightglow(-90, 60) + ", ");
            w.AppendLine(rightglow(-60, 60) + ", ");
            w.AppendLine(rightglow(-30, 50) + ", ");
            w.AppendLine(rightglow(-0, 40) + ", ");
            w.AppendLine(rightglow(30, 40) + ", ");
            w.AppendLine(rightglow(60, 40) + ", ");
            w.AppendLine(rightglow(90, 40) + ", ");
            w.AppendLine(rightglow(120, 40) + " ");

            if (shadow_checksum != __previous_shadow_checksum)
            {
                __previous_shadow_checksum = shadow_checksum;

                set_boxShadow(w.ToString());
            }
        }



        public void __MainApplet_fullscreen()
        {
            this.fullScreenToggle();
        }

        public void __MainApplet_keyPressed(string _key, string _char, Action<string> yield)
        {
            //            KeyEvent(Component source, int id, long when, int modifiers, int keyCode, char keyChar) 
            //source - the Component that originated the event
            //id - an integer identifying the type of event
            //when - a long integer that specifies the time the event occurred
            //modifiers - the modifier keys down during event (shift, ctrl, alt, meta) Either extended _DOWN_MASK or old _MASK modifiers should be used, but both models should not be mixed in one event. Use of the extended modifiers is preferred.
            //keyCode - the integer code for an actual key, or VK_UNDEFINED (for a key-typed event)
            //keyChar - the Unicode character generated by this event, or CHAR_UNDEFINED (for key-pressed and key-released events which do not map to a valid Unicode character)
            try
            {
                var __keyCode = int.Parse(_key);
                var __keyChar = int.Parse(_char);

                //if (__keyChar == 0)
                //    __keyChar = KeyEvent.CHAR_UNDEFINED;


                //Console.WriteLine("__MainApplet_keyPressed " + new { __keyCode, __keyChar });

                base.keyPressed(
                    new java.awt.@event.KeyEvent(
                        this,
                        KeyEvent.KEY_PRESSED,
                        0,
                        __keyCode,
                        __keyChar
                    )
                );
            }
            catch (Exception ex)
            {
                yield(new { ex.Message }.ToString());
            }
        }

        public void __MainApplet_keyReleased(string _key, string _char, Action<string> yield)
        {
            try
            {
                var __keyCode = int.Parse(_key);
                var __keyChar = int.Parse(_char);

                //if (__keyChar == 0)
                //    __keyChar = KeyEvent.CHAR_UNDEFINED;


                //Console.WriteLine("__MainApplet_keyReleased " + new { __keyCode, __keyChar });

                base.keyReleased(
                    new java.awt.@event.KeyEvent(
                        this,
                        KeyEvent.KEY_RELEASED,
                        0,
                       __keyCode,
                       __keyChar
                    )
                );
            }
            catch (Exception ex)
            {
                yield(new { ex.Message }.ToString());
            }

        }

    }
}
